import { makeAutoObservable, reaction } from 'mobx';
import { inject, injectable } from 'inversify';
import { LoginUseCase } from '../usecase/loginUseCase.ts';
import { UserModel } from '../../user/models/user.model.ts';
import { WithError } from '@todo/core';
import { responseLoginDTO } from '../data/auth.dto.ts';
import { AuthInitUseCase } from '../usecase/authInitUseCase.ts';

@injectable()
export class AuthService {
  private afterAuthCallbacks: (() => Promise<void>)[] = [];
  get authenticated() {
    return this.userModel.authenticated;
  }

  constructor(
    @inject(LoginUseCase)
    private loginUseCase: LoginUseCase,
    @inject(UserModel)
    private userModel: UserModel,
    @inject(AuthInitUseCase)
    private authInitUseCase: AuthInitUseCase,
  ) {
    makeAutoObservable(this);
    reaction(
      () => this.userModel.authenticated,
      async (authenticated) => {
        if (authenticated) {
          for (const cb of this.afterAuthCallbacks) {
            await cb();
          }
        }
      },
    );
  }

  async initialize() {
    await this.authInitUseCase.execute(() => this.loginUseCase);
  }

  setAfterAuthCallback(cb: () => Promise<void>) {
    this.afterAuthCallbacks.push(cb);
  }

  async login(
    username: string,
    password: string,
    remember: boolean,
  ): Promise<WithError<responseLoginDTO>> {
    const result = await this.loginUseCase.execute(
      username,
      password,
      remember,
    );
    // this.userModel.authenticated = true;
    return result;
  }

  dispose() {}
}
